home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / closeup / closeup.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  16KB  |  721 lines

  1. /*
  2.  * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /***
  18.     closeup.c - image "magnifier" program
  19.  
  20.     Runs under the window manager.
  21.     Closeup takes an rgb format image on the command line.
  22.     Define XYZOOM as a simple way to demo independent x and y zoom.
  23.     (Use 'make "VCDEFS=-DXYZOOM" closeup')
  24.     -Rolf
  25.  
  26. ***/
  27.  
  28.  
  29. #include <stdio.h>
  30. #include <math.h>
  31. #include <gl.h>
  32. #include <device.h>
  33. #include <image.h>
  34. #include "clang.h"
  35.  
  36.  
  37. void Setup();
  38. void HandleEvents();
  39. void SwapImage();
  40. void ReadImage();
  41. void WriteImage();
  42. void DrawIt();
  43. extern char *malloc();
  44. void ShrinkRow();
  45.  
  46.  
  47. #define PACK_RGB(rgb,r,g,b) { rgb =  \
  48.     (((u_char)b) << 16) | (((u_char)g) << 8) | ((u_char)r); }
  49. #define UNPACK_RGB(rgb,r,g,b) { \
  50.     r = (rgb) & 0xff; \
  51.     g = ((rgb) >> 8) & 0xff; \
  52.     b = ((rgb) >> 16) & 0xff; }
  53.  
  54. long shademode = FLAT ;
  55.  
  56. char CmdName[] = "closeup";
  57. char UsageStr[] = "usage: closeup image-file";
  58.  
  59. u_short ir[1280], ig[1280], ib[1280]; /* temps for reading the image file */
  60.  
  61. typedef struct {
  62.     int mousex, mousey;        /* source location for magnify */
  63.     int width, height;        /* size in pixels of the image */
  64.     long xorigin, yorigin;    /* origin of the window */
  65.     int boxwidth, boxheight;    /* size of the zooming rectangle */
  66.     float xzoom, yzoom;        /* x and y zoom factors */
  67.     Bool zoommode;        /* set when zooming mode is enabled */
  68.     RGBvalue *r, *g, *b;    /* ptrs to the image */
  69. } StateInfo;
  70.     
  71. StateInfo StateBlock;
  72. StateInfo *StatePtr = &StateBlock;
  73.  
  74.  
  75. void
  76. usage()
  77. {
  78.     fprintf(stderr, "%s", UsageStr);
  79.     exit(1);
  80. }
  81.  
  82.  
  83. /***
  84.     Note: getopt code not used yet.
  85. ***/
  86. int
  87. main(argc, argv)
  88. char *argv[];
  89. int argc;
  90. {
  91. int c;
  92. extern int getopt(), optind;
  93. extern char * optarg;
  94.  
  95. #ifdef NOTDEF
  96.     while ((c = getopt(argc, argv, "u:")) != EOF)  {
  97.         switch (c)  {
  98.         default:
  99.         usage();
  100.         }
  101.         }
  102. #endif
  103.  
  104.     if (argc != 2)  {
  105.     fprintf(stderr, "%s\n", UsageStr);
  106.     exit(1);
  107.     }
  108.  
  109.     figure_machine();
  110.     {
  111.         char *t, *strrchr();
  112.         fprintf(stderr, "\n%s: Loading image.  Please wait...",
  113.             (t=strrchr(argv[0], '/')) != NULL ? t+1 : argv[0]);
  114.     }
  115.  
  116.  
  117.     Setup(argv[1], argv[0]);
  118.  
  119.     fprintf(stderr, " Done!\n");
  120.  
  121.     HandleEvents();
  122.  
  123.     /***
  124.     clear the overlay planes before exiting
  125.     ***/
  126.     overlay(2);
  127.     gconfig();
  128.     drawmode(OVERDRAW);
  129.     mapcolor(0, 0,0,0);
  130.     mapcolor(1, 0,255,255);
  131.     color(0);
  132.     clear();
  133.     drawmode(NORMALDRAW);
  134.  
  135.     return 0;
  136. }
  137.  
  138.  
  139. void
  140. Setup(imageName, progname)
  141. char *imageName;
  142. char *progname;
  143. {
  144. char line[100];
  145. int ixzoom, iyzoom;
  146.  
  147.     ReadImage(imageName);
  148.     prefsize((long)StatePtr->width,(long)StatePtr->height);
  149.     {
  150.         char *t, *strrchr();
  151.         winopen((t=strrchr(progname, '/')) != NULL ? t+1 : progname);
  152.     }
  153.     getorigin(&StatePtr->xorigin, &StatePtr->yorigin);
  154.     RGBmode();
  155.     doublebuffer();
  156.     gconfig();
  157.  
  158.     RGBcolor(0, 0, 0);
  159.     clear();
  160.     swapbuffers();
  161.     clear();
  162.     zclear();
  163.  
  164.     overlay(2);
  165.     gconfig();
  166.     drawmode(OVERDRAW);
  167.     mapcolor(0, 0,0,0);
  168.     mapcolor(1, 0,255,255);
  169.     color(0);
  170.     clear();
  171.     drawmode(NORMALDRAW);
  172.  
  173.     qdevice(LEFTMOUSE);
  174.     qdevice(MIDDLEMOUSE);
  175.     qdevice(RIGHTMOUSE);
  176.     qdevice(INPUTCHANGE);
  177.     qdevice(ESCKEY);
  178.     qdevice(GKEY);
  179.     qdevice(FKEY);
  180.     qdevice(WINQUIT);
  181.     qdevice(WINSHUT);
  182.  
  183.     StatePtr->xzoom = 5.0;
  184.     StatePtr->yzoom = 5.0;
  185.     StatePtr->zoommode = FALSE;
  186.     ixzoom = (int) (StatePtr->xzoom + .5);
  187.     iyzoom = (int) (StatePtr->yzoom + .5);
  188.     StatePtr->boxwidth = StatePtr->width / ixzoom;
  189.     StatePtr->boxheight = StatePtr->height / iyzoom;
  190.  
  191.     StatePtr->mousex = 0; /* doesn't really matter */
  192.     StatePtr->mousey = 0;
  193.  
  194.     WriteImage();
  195.  
  196.     qdevice(TIMER1);
  197.     noise(TIMER1, 1);
  198. }
  199.  
  200.  
  201. /***
  202.     contains the main event loop.
  203.     a interval timer is enabled while the window is attached.
  204.     the timer is "paused" during time-consuming sequences
  205.     to avoid timer events flooding the queue.
  206. ***/
  207. void
  208. HandleEvents()
  209. {
  210. short dev, val;
  211. int x, y;
  212. Bool attached = TRUE;
  213. Bool done = FALSE;
  214. #ifdef XYZOOM
  215. Bool xMode = TRUE;
  216. #endif
  217.  
  218.     /* check buttons for mode changes */
  219.     while (dev = qread(&val))  {
  220.  
  221.     /* printf("closeup: event: dev=%d,val=%d\n", dev, val); */
  222.  
  223.     unqdevice(TIMER1);
  224.  
  225.     switch (dev)  {
  226.         case REDRAW:
  227.         pushmatrix();
  228.         drawmode(OVERDRAW);
  229.         fullscrn();
  230.         color(0);
  231.         clear();
  232.         endfullscrn();
  233.         popmatrix();
  234.         drawmode(NORMALDRAW);
  235.         reshapeviewport();
  236.         getorigin(&StatePtr->xorigin, &StatePtr->yorigin);
  237.         WriteImage();
  238.         break;
  239.  
  240.         case LEFTMOUSE:
  241.         if (val)  {
  242. #ifdef XYZOOM
  243.             if (xMode)  {
  244.             if (StatePtr->xzoom < 31.5)  StatePtr->xzoom += 1.0;
  245.             }
  246.             else  {
  247.             if (StatePtr->yzoom < 31.5)  StatePtr->yzoom += 1.0;
  248.             }
  249. #else
  250.             if (StatePtr->xzoom < 31.5)  StatePtr->xzoom += 1.0;
  251.             if (StatePtr->yzoom < 31.5)  StatePtr->yzoom += 1.0;
  252. #endif
  253.             }
  254.         break;
  255.  
  256.         case RIGHTMOUSE:
  257.         if (val)  {
  258. #ifdef XYZOOM
  259.             if (xMode)  {
  260.             if (StatePtr->xzoom > 2.5)  StatePtr->xzoom -= 1.0;
  261.             }
  262.             else  {
  263.             if (StatePtr->yzoom > 2.5)  StatePtr->yzoom -= 1.0;
  264.             }
  265. #else
  266.             if (StatePtr->xzoom > 2.5)  StatePtr->xzoom -= 1.0;
  267.             if (StatePtr->yzoom > 2.5)  StatePtr->yzoom -= 1.0;
  268. #endif
  269.             }
  270.         break;
  271.  
  272.         case INPUTCHANGE:
  273.         /***
  274.             Note: during development (GL & NeWS) there was trouble 
  275.             with this mechanism for attaching focus.
  276.             just comment out this 'case' if the trouble recurs.
  277.         ***/
  278.         if (val)  {  /* mouse entered window */
  279.             attached = TRUE;
  280. #ifdef XYZOOM
  281.             xMode = (xMode) ? FALSE : TRUE;
  282.             printf("closeup: updating %s axis\n", (xMode) ? "x":"y");
  283. #endif
  284.             }
  285.         else  {
  286.             attached = FALSE;
  287.             }
  288.         break;
  289.  
  290.         case GKEY:
  291.         shademode = GOURAUD ;
  292.         break ;
  293.         case FKEY:
  294.         shademode = FLAT ;
  295.         break ;
  296.         case ESCKEY:
  297.         if (val) break;
  298.         case WINQUIT:
  299.         done = TRUE;
  300.         break;
  301.         
  302.         default:
  303.         break;
  304.         }
  305.  
  306.  
  307.     /***
  308.         Compute size of zooming rectangle based on zoom factor.
  309.     ***/
  310.     {
  311.     int ixzoom = (int) (StatePtr->xzoom + .5);
  312.     int iyzoom = (int) (StatePtr->yzoom + .5);
  313.     int boxwidth = StatePtr->width / ixzoom;
  314.     int boxheight = StatePtr->height / iyzoom;
  315.  
  316.     StatePtr->boxwidth = boxwidth;
  317.     StatePtr->boxheight = boxheight;
  318.     }
  319.  
  320.     /***
  321.         Mouse coords are mapped to the window and clamped
  322.         to make the zooming rectangle stay inside the window.
  323.         Note: the "+1" below avoids a visible glitch with rectcopy.
  324.     ***/
  325.     StatePtr->mousex = getvaluator(MOUSEX) - StatePtr->xorigin;
  326.     StatePtr->mousey = getvaluator(MOUSEY) - StatePtr->yorigin;
  327.     if (StatePtr->mousex < 0)  {
  328.         StatePtr->mousex = 0;
  329.         }
  330.     if (StatePtr->mousey <= 0)  {
  331.         StatePtr->mousey = 0 + 1;
  332.         }
  333.     if (StatePtr->mousex > StatePtr->width - StatePtr->boxwidth - 1)  {
  334.         StatePtr->mousex = StatePtr->width - StatePtr->boxwidth - 1;
  335.         }
  336.     if (StatePtr->mousey > StatePtr->height - StatePtr->boxheight - 1)  {
  337.         StatePtr->mousey = StatePtr->height - StatePtr->boxheight - 1;
  338.         }
  339.  
  340.     /***
  341.         switch the displayed buffer when mouse is down
  342.     ***/
  343.     if (getbutton(MIDDLEMOUSE))  {
  344.         if (StatePtr->zoommode != TRUE)  {
  345.         StatePtr->zoommode = TRUE;
  346.         }
  347.         }
  348.     else  {
  349.         if (StatePtr->zoommode != FALSE)  {
  350.         SwapImage(TRUE); /* copy image from z buffer to back buffer */
  351.         swapbuffers();
  352.         StatePtr->zoommode = FALSE;
  353.         }
  354.         }
  355.  
  356.     DrawIt(); /* this may do a swapbuffers() */
  357.     if (attached)  {
  358.         qdevice(TIMER1);
  359.         noise(TIMER1, 1);
  360.         }
  361.         
  362.     if (done) break;
  363.  
  364.     } /* while... */
  365. }
  366.  
  367.  
  368. /***
  369.     perform a rectcopy from the z buffer to the back buffer.
  370.     adjust the destination size to fit the entire window.
  371.     the zooming rectangle is bloated by one pixel (in x and in y)
  372.     to ensure that the destination rectangle fills the window.
  373.     (different zoom factors affect how well the dest rect fits)
  374. ***/
  375. void
  376. DrawIt()
  377. {
  378. int boxwidth = StatePtr->boxwidth;
  379. int boxheight = StatePtr->boxheight;
  380. static int oldmousex, oldmousey, oldboxwidth, oldboxheight;
  381. short junk;
  382.  
  383.     if (StatePtr->zoommode)  {
  384.     /* erase any old rectangle */
  385.     drawmode(OVERDRAW);
  386.     color(0);
  387.     recti(oldmousex, oldmousey,
  388.         oldmousex + oldboxwidth - 1, oldmousey + oldboxheight - 1  );
  389.     drawmode(NORMALDRAW);
  390.  
  391.     readsource(SRC_ZBUFFER);
  392.     if (shademode == FLAT) {
  393.         rectzoom(StatePtr->xzoom, StatePtr->yzoom);
  394.         rectcopy(StatePtr->mousex, StatePtr->mousey,
  395.             StatePtr->mousex + boxwidth, StatePtr->mousey + boxheight,
  396.             0, 0  );
  397.         }
  398.     else 
  399.        /* Gouraud Shading */
  400.         smoothcopy() ;
  401.  
  402.     gRGBcolor(&junk, &junk, &junk); /* hack to flush pipe */
  403.     swapbuffers();
  404.     }
  405.     else  {
  406.     /* draw zooming rectangle in overlays when it changes */
  407.     if ((StatePtr->mousex == oldmousex) &&
  408.         (StatePtr->mousey == oldmousey) &&
  409.         (boxwidth == oldboxwidth) &&
  410.         (boxheight == oldboxheight)  )  {
  411.         ;
  412.         }
  413.     else  {
  414.         drawmode(OVERDRAW);
  415.         color(0);
  416.         recti(oldmousex, oldmousey,
  417.         oldmousex + oldboxwidth - 1, oldmousey + oldboxheight - 1  );
  418.         color(1);
  419.         recti(StatePtr->mousex, StatePtr->mousey,
  420.         StatePtr->mousex + boxwidth - 1,
  421.         StatePtr->mousey + boxheight - 1  );
  422.         oldmousex = StatePtr->mousex;
  423.         oldmousey = StatePtr->mousey;
  424.         oldboxwidth = boxwidth;
  425.         oldboxheight = boxheight;
  426.         drawmode(NORMALDRAW);
  427.         }
  428.     }
  429. }
  430.  
  431. /* store pixels read for gouraud zoom */
  432. unsigned long *cbuf;
  433.  
  434. makebuf() {
  435.     /* compute source rect size based on window size and zoom factor */
  436.     /* malloc a buffer based on the computed size */
  437.     static size = 0;
  438.     int msize;
  439.     long xsrc,ysrc;
  440.  
  441.     int ixzoom = (int) (StatePtr->xzoom + .5);
  442.     int iyzoom = (int) (StatePtr->yzoom + .5);
  443.  
  444.     /* Gouraud shading requires (n+1) points to gouraud shade (n) points */
  445.     StatePtr->width++;        /* n+1 */
  446.     StatePtr->height++;
  447.  
  448.     StatePtr->boxwidth = StatePtr->width / ixzoom;
  449.     StatePtr->boxheight =StatePtr->height / iyzoom;
  450.  
  451.     xsrc = (long)(StatePtr->width) ;
  452.     ysrc = (long)(StatePtr->height) ;
  453.     msize = (xsrc) * (ysrc);
  454.     if (msize != size) {
  455.     stepunit((int)ixzoom,(int)iyzoom);
  456.     winconstraints();
  457.     if (size > 0)
  458.         free(cbuf);
  459.     if ((cbuf=(unsigned long*)malloc(msize*4)) == 0) {
  460.         fprintf(stderr,"  ERROR: can't malloc %d longs. abort.\n",msize);
  461.         gexit() ;
  462.         exit(1);
  463.     }
  464.     size = msize;
  465.     }
  466. }
  467.  
  468. smoothcopy() {
  469.     /* read specified pixels, then draw gouraud shaded polygons */
  470.     /* assume that matrix and viewport are set up 1-to-1 object-to-pixel */
  471.     register x,y;
  472.     register unsigned long *cp0,*cp1;
  473.     register short *cp0s,*cp1s;
  474.     long width;
  475.     long height;
  476.     long xfinal,yfinal;
  477.     long vbuf[8];
  478.     float fzoomx;
  479.     float fzoomy;
  480.     float fzoomz;
  481.  
  482.     makebuf() ;
  483.  
  484.     width = StatePtr->boxwidth ;
  485.     height = StatePtr->boxheight ;
  486.     xfinal = width ;
  487.     yfinal = height ;
  488.  
  489.     lrectread(StatePtr->mousex,StatePtr->mousey,
  490.           (StatePtr->mousex + width - 1),
  491.           (StatePtr->mousey + height - 1),cbuf);
  492.  
  493.     pushmatrix();
  494.     fzoomx = StatePtr->xzoom ;
  495.     fzoomy = StatePtr->yzoom ;
  496.     fzoomz = 0.0 ;
  497.     scale((float)fzoomx,(float)fzoomy,(float)fzoomz);
  498.     for (y=0; y<yfinal; y++) {
  499.     vbuf[1] = vbuf[3] = y;
  500.     vbuf[5] = vbuf[7] = y+1;
  501.         cp0 = &cbuf[y * width];
  502.         cp1 = &cbuf[(y+1) * width + 1];
  503.         for (x=0; x<xfinal; x++) {
  504.         vbuf[0] = vbuf[6] = x;
  505.         vbuf[2] = vbuf[4] = x+1;
  506.         bgnpolygon();
  507.         cpack(*cp0++);
  508.         v2i(vbuf);
  509.         cpack(*cp0);
  510.         v2i(vbuf+2);
  511.         cpack(*cp1--);
  512.         v2i(vbuf+4);
  513.         cpack(*cp1++);
  514.         v2i(vbuf+6);
  515.         endpolygon();
  516.         cp1 += 1;
  517.         }
  518.     }
  519.     popmatrix();
  520.     /* Restore Correct Values */
  521.     --StatePtr->width ;        /* n */
  522.     --StatePtr->height ;
  523. }
  524.  
  525.  
  526. void
  527. ReadImage(name)
  528. char *name;
  529. {
  530. IMAGE *image;
  531. RGBvalue *r, *g, *b, *rp, *gp, *bp;
  532. int i, j, y, dx, dy;
  533.  
  534.     if ((image = iopen(name,"r")) == NULL)  {
  535.     fprintf(stderr, "%s: can't open image file %s\n", CmdName, name);
  536.     exit(1);
  537.     }
  538.     if (image->zsize < 3)  {
  539.     fprintf(stderr, "%s: image file is not an rgb image", CmdName);
  540.     exit(1);
  541.     }
  542.     dx = image->xsize;
  543.     dy = image->ysize;
  544.  
  545.     r = (RGBvalue *) malloc(dx*dy*sizeof(RGBvalue));
  546.     g = (RGBvalue *) malloc(dx*dy*sizeof(RGBvalue));
  547.     b = (RGBvalue *) malloc(dx*dy*sizeof(RGBvalue));
  548.  
  549.     for (y=0, rp=r, gp=g, bp=b;  y < dy;  y++, rp+=dx, gp+=dx, bp+=dx)  {
  550.     getrow(image, ir, y, 0); ShrinkRow(dx, ir, rp);
  551.     getrow(image, ig, y, 1); ShrinkRow(dx, ig, gp);
  552.     getrow(image, ib, y, 2); ShrinkRow(dx, ib, bp);
  553.     }
  554.  
  555.     /***
  556.     save image parameters in global state (for WriteImage()).
  557.     ***/
  558.     StatePtr->r = r;
  559.     StatePtr->g = g;
  560.     StatePtr->b = b;
  561.     StatePtr->width = dx;
  562.     StatePtr->height = dy;
  563. }
  564.  
  565.  
  566. /***
  567.     Assumes double buffer mode.
  568. ***/
  569. void
  570. Drawit()
  571. {
  572. RGBvalue *r, *g, *b, *rp, *gp, *bp;
  573. int y, dx, dy;
  574.  
  575.     /***
  576.     get image parameters from global state.
  577.     ***/
  578.     r = StatePtr->r;
  579.     g = StatePtr->g;
  580.     b = StatePtr->b;
  581.     dx = StatePtr->width;
  582.     dy = StatePtr->height;
  583.  
  584.     /***
  585.     write out image to the all buffers (especially the zbuffer).
  586.     ***/
  587.  
  588. #ifndef NOTDEF
  589.     for (y=0, rp=r, gp=g, bp=b;  y < dy;  y++, rp+=dx, gp+=dx, bp+=dx) {
  590.     cmov2i(0, y);
  591.     writeRGB((short) dx, rp, gp, bp);
  592.     }
  593. #else
  594.     /***
  595.     Note: this block of code doesn't work yet...
  596.     ***/
  597.     {
  598.     int x, y;
  599.     int *pixelp, pixelBuf[1280];
  600.  
  601.     rp = r;  gp = g;  bp = b;
  602.     for (y = 0;  y < dy;  y++)  {
  603.     pixelp = pixelBuf;
  604.     for (x = 0;  x < dx;  x++)  {
  605.         PACK_RGB(*pixelp, *rp, *gp, *bp);
  606.         pixelp++, rp++, gp++, bp++;
  607.         }
  608.     (void) lrectwrite(0, y, dx - 1, y, pixelp);
  609.     }
  610.     }
  611. #endif
  612.  
  613. }
  614.  
  615. static enum {
  616.     MACH_ECLIPSE,
  617.     MACH_CLOVER2,    /* Doesn't work on CLOVER1 */
  618.     MACH_STAPUFT,
  619.     MACH_VENICE,
  620.     MACH_ELAN
  621. } machine;
  622.  
  623. figure_machine()
  624. {
  625.     char t[20];
  626.     char mystring[60];
  627.     static char ecl[] = "GL4DPI";
  628.     static char cl2[] = "GL4DGT";
  629.     static char stp[] = "GL4DVGX";
  630.     static char ven[] = "GL4DRE";
  631.     static char eln[] = "GL4DXG";
  632.  
  633.     gversion(t);
  634.     if (strncmp(t, ecl, strlen(ecl)) == 0)
  635.         machine = MACH_ECLIPSE;
  636.     else if (strncmp(t, cl2, strlen(cl2)) == 0)
  637.         machine = MACH_CLOVER2;
  638.     else if (strncmp(t, stp, strlen(stp)) == 0)
  639.         machine = MACH_STAPUFT;
  640.     else if (strncmp(t, ven, strlen(ven)) == 0)
  641.         machine = MACH_VENICE;
  642.     else if (strncmp(t, eln, strlen(eln)) == 0)
  643.         machine = MACH_ELAN;
  644.     else {
  645.         sprintf(mystring, "inform 'Sorry, closeup does not work on %s machines'", t);
  646.         system(mystring);
  647.         gexit();
  648.         exit(1);
  649.     }
  650.     if ((getgdesc(GD_BITS_NORM_DBL_RED) + getgdesc(GD_BITS_NORM_DBL_GREEN) +        getgdesc(GD_BITS_NORM_DBL_BLUE)) < 12) {
  651.         sprintf(mystring, "Sorry, closeup needs at least 12 bitplanes to run.");
  652.         system(mystring);
  653.         gexit();
  654.         exit(1);
  655.     }
  656. }
  657.  
  658. void
  659. WriteImage() 
  660. {
  661.     if (machine == MACH_ECLIPSE ||
  662.         machine == MACH_ELAN)
  663.     {
  664.         zdraw(TRUE);
  665.         Drawit();
  666.         zdraw(FALSE);
  667.         frontbuffer (TRUE);
  668.         Drawit();
  669.     }
  670.     else
  671.     {
  672.         zdraw(TRUE);
  673.         frontbuffer(TRUE);
  674.         Drawit();
  675.         zdraw(FALSE);
  676.     }
  677.     frontbuffer(FALSE);
  678. }
  679.  
  680. /***
  681.     Copy an image from (to) the zbuffer to (from) the back buffer.
  682.     The image is the entire contents of the window.
  683.     Assumes doublebuffer mode.
  684. ***/
  685. void
  686. SwapImage(fromz)
  687. Bool fromz; /* TRUE = copy from "z" to "back" buffer, FALSE = vice versa */
  688. {
  689. short junk;
  690.  
  691.     if (fromz)  {
  692.     readsource(SRC_ZBUFFER);
  693.     frontbuffer(FALSE);
  694.     backbuffer(TRUE);
  695.     zdraw(FALSE);
  696.     }
  697.     else  {
  698.     fprintf(stderr, "SwapImage: doesn't work!\n");
  699.     }
  700.  
  701.     rectzoom(1.0, 1.0);
  702.     rectcopy(0, 0, StatePtr->width - 1, StatePtr->height - 1, 0, 0);
  703.  
  704.     gRGBcolor(&junk, &junk, &junk); /* hack to flush pipe */
  705. }
  706.  
  707.  
  708. /***
  709.     Shrink an array of shorts into an array of bytes.
  710. ***/
  711. void
  712. ShrinkRow(cols, sp, bp)
  713. int cols;
  714. u_short *sp;
  715. RGBvalue *bp;
  716. {
  717.     while (cols--)  {
  718.     *bp++ = *sp++;
  719.     }
  720. }
  721.